package repository

import (
	"fmt"
	"log"
	"os"

	"database/sql"

	_ "github.com/go-sql-driver/mysql"
	yaml "sigs.k8s.io/yaml/goyaml.v3"
)

type mysqlConfig struct {
	MySQL MySQLConfig `yaml:"mysql"`
}

type MySQLConfig struct {
	Database string `yaml:"database"`
	User     string `yaml:"user"`
	Password string `yaml:"password"`
	Host     string `yaml:"host"`
	Port     string `yaml:"port"`
}

type InventoryRepository struct {
	db *sql.DB
}

func NewMySQLRepository(configPath string) *InventoryRepository {
	yamlFile, err := os.ReadFile(configPath)
	if err != nil {
		log.Fatalf("读取配置文件失败: %v", err)
	}

	var cfg mysqlConfig
	err = yaml.Unmarshal(yamlFile, &cfg)
	if err != nil {
		log.Fatalf("解析配置文件失败: %v", err)
	}

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		cfg.MySQL.User, cfg.MySQL.Password, cfg.MySQL.Host, cfg.MySQL.Port, cfg.MySQL.Database)

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		log.Fatalf("连接数据库失败: %v", err)
	}

	return &InventoryRepository{db: db}
}

//手工创建stock表
// CREATE TABLE `stock` (
// 	`productid` varchar(255) NOT NULL,
// 	`quantity` int(11) NOT NULL,
// 	PRIMARY KEY (`productid`)
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

// stock表插入数据
func (r *InventoryRepository) ReserveStock(productID string, quantity int32) error {
	// // 检查库存是否充足
	// var currentQuantity int32
	// err := r.db.QueryRow("SELECT quantity FROM stock WHERE productid = ?", productID).Scan(&currentQuantity)
	// if err != nil {
	// 	return err
	// }
	// if currentQuantity < quantity {
	// 	return fmt.Errorf("库存不足")
	// }
	// 通过事务锁更新库存
	tx, err := r.db.Begin()
	if err != nil {
		return err
	}
	_, err = tx.Exec("SELECT quantity FROM stock WHERE productid = ? FOR UPDATE", productID)
	if err != nil {
		return err
	}
	_, err = tx.Exec("UPDATE stock SET quantity = quantity - ? WHERE productid = ?", quantity, productID)
	if err != nil {
		return err
	}
	return tx.Commit()
}

func (r *InventoryRepository) ReleaseStock(productID string, quantity int32) error {
	tx, err := r.db.Begin()
	if err != nil {
		return err
	}
	_, err = tx.Exec("SELECT quantity FROM stock WHERE productid = ? FOR UPDATE", productID)
	if err != nil {
		return err
	}
	_, err = tx.Exec("UPDATE stock SET quantity = quantity + ? WHERE productid = ?", quantity, productID)
	if err != nil {
		return err
	}
	return tx.Commit()
}

func (r *InventoryRepository) QueryStock(productID string) (int32, error) {
	var quantity int32
	err := r.db.QueryRow("SELECT quantity FROM stock WHERE productid = ?", productID).Scan(&quantity)
	if err != nil {
		return 0, err
	}
	return quantity, nil
}

func (r *InventoryRepository) CreateStock(productID string, quantity int32) error {
	_, err := r.db.Exec("INSERT INTO stock (productid, quantity) VALUES (?, ?)", productID, quantity)
	if err != nil {
		return err
	}
	return nil
}
